package com.hmall.user.service.impl;


import cn.hutool.crypto.digest.DigestUtil;
import com.hmall.user.dto.LoginDto;
import com.hmall.user.dto.UserDto;
import com.hmall.user.mapper.UserMapper;
import com.hmall.user.pojo.User;
import com.hmall.user.service.UserService;
import com.hmall.user.vo.LoginVo;
import com.hmall.utils.AssertUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @author mengjie
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public LoginVo queryListByName(LoginDto dto) {
        //获取用户名和密码
        String username = dto.getUsername();
        String password = dto.getPassword();
        //根据用户名、密码查询tb_user表查询一条数据
        User user = userMapper.queryListByName(username);
        //数据库对应的哈希值密码
        String inputPassword = user.getPassword();
        // 对用户输入的密码进行bcrypt比对处理
        AssertUtils.assertTrue(DigestUtil.bcryptCheck(password, inputPassword), "密码错误");

        //对user判断，如果有数据，表示登录成功，如果没有数据，表示登录失败
        AssertUtils.assertNotNull(user, "参数错误-登录失败");
        //登录成功：创建LoginVo对象，返回
        LoginVo loginVo = LoginVo.builder()
                .username(user.getUsername())
                .token(String.valueOf(user.getId()))
                .build();
        return loginVo;
    }

    /**
     * 检查用户名称是的存在
     *
     * @param value
     * @return
     */

    @Override
    public boolean checkUserName(String value) {
        User user = userMapper.checkUserName(value);
        if (user != null) {
            return false;
        }
        return true;
    }

    /**
     * 检查手机号是否存在
     *
     * @param value
     * @return
     */
    @Override
    public boolean checkPhone(String value) {
        User user = userMapper.checkPhone(value);
        if (user != null) {
            return false;
        }
        return true;
    }

    @Override
    public void addUser(UserDto dto) {
        //防止注册数据为空 校验空指针
        AssertUtils.assertNotNull(dto, "注册数据为空");
        log.info("code{}", dto.getCode());

        //判断一下两次密码是否一致（如果错误，抛异常）
        AssertUtils.assertEquals(dto.getPassword(), dto.getConfirmPassword(), "两次密码不一致");

        //获取Redis中的验证码 并且判断是否为空
        String redisKv = redisTemplate.opsForValue().getAndSet(dto.getPhone(), dto.getCode());
        // 验证是否过期
        AssertUtils.assertNotNull(redisKv, "验证码已过期,请重新发送");

        //判断验证码是否为空（如果错误，抛异常）
        AssertUtils.assertNotNull(dto.getCode(), "验证码不可为空");

        //判断用户输入的验证码与redis中是否匹配
        AssertUtils.assertEquals(dto.getCode(), redisKv, "验证码错误");

        //將用户输入的用户名，手机号 存入Redis中
        redisTemplate.opsForValue().set(dto.getPhone(), dto.getUsername());

        // 验证用户名是否已注册
        User userName = userMapper.checkUserName(dto.getUsername());
        AssertUtils.assertNotEquals(userName, dto.getUsername(), "用户名已存在，请重新输入");

        //直接添加到数据库
        User user = new User();
        user.setUsername(dto.getUsername());
        // 注册密码加密
        user.setPassword(DigestUtil.bcrypt(dto.getPassword()));
        user.setPhone(dto.getPhone());
        user.setStatus(1); //1正常  2冻结
        user.setCreated(new Date());
        user.setUpdated(new Date());
        user.setBalance(10000L);
        userMapper.addUser(user);
    }
}